package ioio.examples.simple;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.Math;

import ioio.lib.api.AnalogInput;
import ioio.lib.api.DigitalOutput;
import ioio.lib.api.IOIO;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.AbstractIOIOActivity;
import android.media.AudioManager;
import android.media.SoundPool;
import android.media.SoundPool.OnLoadCompleteListener;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;

public class IOIOSimpleApp extends AbstractIOIOActivity {

    private TextView textView_;
    private ToggleButton toggleButton_;
    private EditText editField;
    int soundID = 0;
    int soundID2 = 0;
    int soundID3 = 0;
    private SoundPool soundPool;
    boolean sndLoaded = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        textView_ = (TextView) findViewById(R.id.TextView);
        toggleButton_ = (ToggleButton) findViewById(R.id.ToggleButton);
        toggleButton_.setOnClickListener(listener);

        editField = (EditText) findViewById(R.id.editText1);


        //Setting up Sound
        this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
        soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
        //Probably don't need this here
        soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {

            public void onLoadComplete(SoundPool soundPool, int sampleId,
                    int status) {
                sndLoaded = true;
            }
        });
        soundID = soundPool.load(this, R.raw.sound1, 1);
        soundID2 = soundPool.load(this, R.raw.sound2, 1);
        soundID3 = soundPool.load(this, R.raw.sound3, 1);
    }
    private OnClickListener listener = new OnClickListener() {

        public void onClick(View v) {
            if (toggleButton_.isChecked()) {
                // Popup for turning sensor on
                Toast.makeText(getBaseContext(), "Turning Sensor On", Toast.LENGTH_SHORT).show();
                //setData("Sensor On");

                // Get what is in editField and store to card
                // Convert from Editable to string
                String inputString = "\n==================="
                        + "=========================================";
                writeToCard(inputString, "sensor_data.txt");
                inputString = editField.getText().toString();
                writeToCard(inputString, "sensor_data.txt");

            } else {
                Toast.makeText(getBaseContext(), "Turning Sensor Off", Toast.LENGTH_SHORT).show();
                //addData("Sensor Off\n");
            }
        }
    };

    class IOIOThread extends AbstractIOIOActivity.IOIOThread {

        private AnalogInput input_;
        //private PwmOutput pwmOutput_;
        private DigitalOutput led_;
        //private String enterStr;
        private audioClass audio;
        
        private AnalogInput knob;
        private AnalogInput monitor; //****************************************************
        private AnalogInput sensor_center;
        private AnalogInput sensor_left;
        private AnalogInput sensor_right;
        private DigitalOutput rx_center;
        private DigitalOutput rx_side;

        public void setup() throws ConnectionLostException {
            try {
                //  input_ = ioio_.openAnalogInput(31);
                //    pwmOutput_ = ioio_.openPwmOutput(12, 100);

            	knob = ioio_.openAnalogInput(37);
            	monitor = ioio_.openAnalogInput(38); //****************************************************
            	
                sensor_center = ioio_.openAnalogInput(33);
                sensor_left = ioio_.openAnalogInput(32);
                sensor_right = ioio_.openAnalogInput(34);

                rx_center = ioio_.openDigitalOutput(11, DigitalOutput.Spec.Mode.OPEN_DRAIN, false);
                rx_side = ioio_.openDigitalOutput(10, DigitalOutput.Spec.Mode.OPEN_DRAIN, false);

                led_ = ioio_.openDigitalOutput(IOIO.LED_PIN, true);
                enableUi(true);
                rx_center.write(true);
                rx_side.write(false);

                sleep(50);

            } catch (ConnectionLostException e) {
                //enableUi(false);
                throw e;
            } catch (Throwable e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        }
        
        double knob_val = 0;
        
        double mon_val = 0; //****************************************************
        int perc = 0;
        
        double[] sample_center = new double[5];
        double[] sample_left = new double[5];
        double[] sample_right = new double[5];
        
        int center_reading_id = 0;
        int left_reading_id = 0;
        int right_reading_id = 0;
        
        pkg496_spu.spu spu = new pkg496_spu.spu();
        pkg496_spu.battery battery = new pkg496_spu.battery();
        
        double center_output;
        double left_output;
        double right_output;
        
        int[] center_play_flags = {0, 0, 0, 0, 0};
        int[] left_play_flags = {0, 0, 0, 0, 0};
        int[] right_play_flags = {0, 0, 0, 0, 0};
        
        String output_str;
        String knob_str;
        String bat_str;
        
        long startTime;
        long endTime;
        long exeTime;
        
        public void loop() throws ConnectionLostException {
            try {
                startTime = System.nanoTime();
                
                boolean sound_front = false;
                boolean sound_side = false;
                
                knob_val = knob.read();
                mon_val = monitor.getVoltage(); //****************************************************
                
                knob_str = Double.toString(knob_val);
                perc = battery.battery(mon_val);
                bat_str = Integer.toString(perc);//Integer.toString(perc);

                try {
                    sample_center[center_reading_id] = sensor_center.read();
                    center_reading_id++;

                    if (center_reading_id == sample_center.length - 1) {
                        center_output = spu.spu(sample_center);
                        center_reading_id = 0;

                        if (center_output == -1) {
                            output_str = "Front: N/A";
                        } else {
                            output_str = "Front: " + Double.toString(center_output) + "m";
                        }

                        if (play_sound_parse(center_output, center_play_flags)) {
                            sound_front = true;
                        }

                        // setText(output_str);
                        // writeToCard(output_str);
                    }

                    rx_center.write(false);
                    rx_side.write(true);
                } finally {
                    endTime = System.nanoTime();
                }

                exeTime = (long) ((endTime - startTime) / 1.0E6);

                //writeToCard(Long.toString(exeTime), "exe_timing.txt");
                
                if  (exeTime > 0 && exeTime <= 50) {
                	sleep(50 - exeTime);
                } else if (exeTime <= 0) {
                	sleep(50);
                }

                startTime = System.nanoTime();

                try {
                    boolean sound_parse = false;

                    sample_left[left_reading_id] = sensor_left.read();
                    left_reading_id++;

                    if (left_reading_id == sample_left.length - 1) {
                        left_output = spu.spu(sample_left);
                        left_reading_id = 0;

                        String tmp_left;

                        if (left_output == -1) {
                            tmp_left = "Left: N/A";
                        } else {
                            tmp_left = "Left: " + Double.toString(left_output) + "m";
                        }

                        output_str = tmp_left + " | " + output_str;

                        //setText(output_str);
                        //writeToCard(output_str);
                    }

                    sample_right[right_reading_id] = sensor_right.read();
                    right_reading_id++;

                    if (right_reading_id == sample_right.length - 1) {
                        right_output = spu.spu(sample_right);
                        right_reading_id = 0;

                        if (right_output == -1) {
                            output_str += " | " + "Right: N/A";
                        } else {
                            output_str += " | " + "Right: " + Double.toString(right_output) + "m";
                        }

                        sound_parse = true;

                        output_str += " | Knob: " + knob_str;
                        output_str += " | Battery: " + bat_str + "%";
                        setText(output_str);
                        writeToCard(output_str, "sensor_data.txt");
                    }

                    if (sound_parse) {
                        if (play_sound_parse(left_output, left_play_flags) || play_sound_parse(right_output, right_play_flags)) {
                            sound_side = true;
                        }
                    }

                    if (sound_front) {
                    	playSound(1);
                    } else if (sound_side) {
                    	playSound(2);
                    }
                    
                    rx_center.write(true);
                    rx_side.write(false);

                } finally {
                    endTime = System.nanoTime();
                }

                exeTime = (long) ((endTime - startTime) / 1.0E6);

                //writeToCard(Long.toString(exeTime), "exe_timing.txt");
                
                if  (exeTime > 0 && exeTime <= 50) {
                	sleep(50 - exeTime);
                } else if (exeTime <= 0) {
                	sleep(50);
                }

//                if (toggleButton_.isChecked()) {
//                    writeToCard(Float.toString(reading));
//                }
                //pwmOutput_.setPulseWidth(500 + seekBar_.getProgress() * 2);
//                led_.write(toggleButton_.isChecked());
//                sleep(10);
            } catch (InterruptedException e) {
                ioio_.disconnect();
            } catch (ConnectionLostException e) {
                //enableUi(false);
                throw e;
            }
        }
    }

    @Override
    protected AbstractIOIOActivity.IOIOThread createIOIOThread() {
        return new IOIOThread();
    }

    private void playSound(int id) {
        AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
        float actualVolume = (float) audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
        float maxVolume = (float) audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        float volume = actualVolume / maxVolume;
        // Is the sound loaded already?
        //if (sndLoaded) {
        if (id == 0) {
            soundPool.play(soundID, volume, volume, 1, 0, 1f);
        } else if (id == 1) {
            soundPool.play(soundID2, volume, volume, 1, 0, 1f);
        } else if (id == 2) {
            soundPool.play(soundID3, volume, volume, 1, 0, 1f);
        }
        Log.e("Test", "Played sound");
        //}
    }

    private void enableUi(final boolean enable) {
        runOnUiThread(new Runnable() {

            @Override
            public void run() {
                toggleButton_.setEnabled(enable);
            }
        });
    }

    private void setText(final String str) {
        runOnUiThread(new Runnable() {

            @Override
            public void run() {
                textView_.setText(str);
            }
        });
    }

    public void writeToCard(String data, String filename) {
        try {
            File root = Environment.getExternalStorageDirectory();
            if (root.canWrite()) {
                File dataFile = new File(root, filename);
                FileWriter dataWriter = new FileWriter(dataFile, true);
                dataWriter.append(data + "\n");
                dataWriter.close();
            } else {
                Log.i("SENSORIO", "cannot write to sdcard\n");
            }
        } catch (IOException e) {
            Log.e("tag", "Could not write to file " + e.getMessage());
        }
    }

    private boolean play_sound_parse(double output, int[] play_flags) {
        if (output == -1) {
            for (int i = 0; i < play_flags.length; i++) {
                play_flags[i] = 0;
            }
        } else {
            if (output < 0.5) {
                for (int i = 0; i < play_flags.length; i++) {
                    if (i == 0 || i == 1) {
                        play_flags[i] = 1;
                    } else {
                        play_flags[i] = 0;
                    }
                }
            } else if (output >= 0.5 && output < 1.5) {
                if (play_flags[2] == 0) {
                    for (int i = 0; i < play_flags.length; i++) {
                        if (i == 0 || i == 2) {
                            play_flags[i] = 1;
                        } else {
                            play_flags[i] = 0;
                        }
                    }
                } else if (play_flags[2] == 1) {
                    for (int i = 0; i < play_flags.length; i++) {
                        play_flags[i] = 0;
                    }
                }
            } else if (output >= 1.5 && output < 2.5) {
                if (play_flags[3] == 0) {
                    for (int i = 0; i < play_flags.length; i++) {
                        if (i == 0 || i == 3) {
                            play_flags[i] = 1;
                        } else {
                            play_flags[i] = 0;
                        }
                    }
                } else if (play_flags[3] == 1) {
                    for (int i = 0; i < play_flags.length; i++) {
                        if (i == 3) {
                            play_flags[i] = 2;
                        } else {
                            play_flags[i] = 0;
                        }
                    }
                } else if (play_flags[3] == 2) {
                    for (int i = 0; i < play_flags.length; i++) {
                        play_flags[i] = 0;
                    }
                }
            } else if (output >= 2.5 && output < 3.5) {
                if (play_flags[4] == 0) {
                    for (int i = 0; i < play_flags.length; i++) {
                        if (i == 0 || i == 4) {
                            play_flags[i] = 1;
                        } else {
                            play_flags[i] = 0;
                        }
                    }
                } else if (play_flags[4] == 1) {
                    for (int i = 0; i < play_flags.length; i++) {
                        if (i == 4) {
                            play_flags[i] = 2;
                        } else {
                            play_flags[i] = 0;
                        }
                    }
                } else if (play_flags[4] == 2) {
                    for (int i = 0; i < play_flags.length; i++) {
                        if (i == 4) {
                            play_flags[i] = 3;
                        } else {
                            play_flags[i] = 0;
                        }
                    }
                } else if (play_flags[4] == 3) {
                    for (int i = 0; i < play_flags.length; i++) {
                        play_flags[i] = 0;
                    }
                }
            }
        }

        if (play_flags[0] == 1) {
            return true;
        } else {
            return false;
        }
    }
}
